package dilmaj.server;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import javax.jdo.PersistenceManager;

import org.w3c.dom.Document;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import dilmaj.client.AreaService;
import dilmaj.client.AreaServiceAsync;
import dilmaj.client.CommentJDO;
import dilmaj.client.EntryComparator;
import dilmaj.client.EntryJDOComparator;
import dilmaj.client.StarEntryJDO;
import dilmaj.client.StarService;
import dilmaj.client.TermJDO;
import dilmaj.client.TermService;
import dilmaj.client.TermServiceAsync;
import dilmaj.client.UserService;
import dilmaj.client.UserServiceAsync;
import dilmaj.shared.CommentVO;
import dilmaj.shared.StarAreaVO;
import dilmaj.shared.StarCommentVO;
import dilmaj.shared.StarEntryVO;
import dilmaj.shared.StarLanguageVO;
import dilmaj.shared.StarPrivilegeVO;
import dilmaj.shared.StarSourceVO;
import dilmaj.shared.StarSuggestionVO;
import dilmaj.shared.StarTermVO;
import dilmaj.shared.StarUseCaseVO;
import dilmaj.shared.TermVO;

public class StarServiceImpl extends RemoteServiceServlet implements
		StarService {
	Object[] jdoArray;
	Object[] voArray;
	List<StarEntryJDO> starEntryJDOs;
	ArrayList<StarEntryVO> starEntryVOs;
	
	public List<StarEntryVO> loadAll() {
		starEntryVOs=new ArrayList<StarEntryVO>();
		try {
		    PersistenceManager pm = PMF.get().getPersistenceManager();
		    String query = "select from " + StarEntryJDO.class.getName();
		    starEntryJDOs = (List<StarEntryJDO>) pm.newQuery(query).execute();
		    List<StarEntryJDO> nullJDOs=new ArrayList<StarEntryJDO>();
		    
		    Iterator iterator=starEntryJDOs.iterator();
		    while (iterator.hasNext()) {
		    	StarEntryJDO currentStarEntry=(StarEntryJDO)iterator.next();
		    	String caption=currentStarEntry.getCaption();
		    	if (caption!=null && caption.length()!=0) {
			    	String title=currentStarEntry.getTitle();
			    	StarEntryVO starEntryVO=null;
			    	if (title==null) {
			    		starEntryVO=new StarEntryVO(currentStarEntry);
			    	} else if (title.compareTo("")==0) {
			    		starEntryVO=new StarEntryVO(currentStarEntry);
			    	} else if (title.compareTo("term")==0) {
			    		starEntryVO=new StarTermVO(currentStarEntry);
			    	} else if (title.compareTo("area")==0) {
			    		starEntryVO=new StarAreaVO(currentStarEntry);
			    	} else if (title.compareTo("suggestion")==0) {
			    		starEntryVO=new StarSuggestionVO(currentStarEntry);
			    	} else if (title.compareTo("usecase")==0) {
			    		starEntryVO=new StarUseCaseVO(currentStarEntry);
			    	} else if (title.compareTo("source")==0) {
			    		starEntryVO=new StarSourceVO(currentStarEntry);
			    	} else if (title.compareTo("language")==0) {
			    		starEntryVO=new StarLanguageVO(currentStarEntry);
			    	} else if (title.compareTo("comment")==0) {
			    		starEntryVO=new StarCommentVO(currentStarEntry);
			    	} else if (title.compareTo("usecase")==0) {
			    		starEntryVO=new StarUseCaseVO(currentStarEntry);
			    	} else if (title.compareTo("privilege")==0) {
			    		starEntryVO=new StarPrivilegeVO(currentStarEntry);
			    	} else {
			    		starEntryVO=new StarEntryVO(currentStarEntry);
			    	}
			    	starEntryVOs.add(starEntryVO);
		    	} else {
		    		nullJDOs.add(currentStarEntry);
		    	}
		    }
		    starEntryJDOs.removeAll(nullJDOs);
		    
		    jdoArray=starEntryJDOs.toArray();
		    Arrays.sort(jdoArray, new EntryJDOComparator());
		    voArray=starEntryVOs.toArray();
		    Arrays.sort(voArray, new EntryComparator());
		    
		    for (int i=0;i<jdoArray.length;i++) {
		    	List<Long> attachments=((StarEntryJDO)jdoArray[i]).getAttachments();
		    	StarEntryVO baseVO=(StarEntryVO)voArray[i];
		    	if (baseVO.getCaption().contains("yyy")) {
		    		int k=0;
		    	}
		    	if (attachments!=null) {
			    	Iterator idIterator=attachments.iterator();
			    	while (idIterator.hasNext()) {
			    		Long currentID=(Long)idIterator.next();
			    		
			    		for (int j=0;j<voArray.length;j++) {
			    			StarEntryVO searchVO=(StarEntryVO)voArray[j];
			    			
			    			if (searchVO.getId().longValue()==currentID.longValue())
			    				baseVO.addAttachment(searchVO);
			    		}
			    	}
		    	}
		    }
		    
		    pm.close();
		    return starEntryVOs;
		} catch (Exception e) {
		    return starEntryVOs;
		}
	}

	public static List<StarEntryVO> staticLoadAll() {
		List<StarEntryVO> staticVOs=new ArrayList<StarEntryVO>();
		List<StarEntryJDO> staticJDOs=new ArrayList<StarEntryJDO>();
		try {
		    PersistenceManager pm = PMF.get().getPersistenceManager();
		    String query = "select from " + StarEntryJDO.class.getName();
		    staticJDOs = (List<StarEntryJDO>) pm.newQuery(query).execute();
		    
		    Iterator iterator=staticJDOs.iterator();
		    while (iterator.hasNext()) {
		    	StarEntryJDO jdo=(StarEntryJDO)iterator.next();
		    	StarEntryVO vo=new StarEntryVO(jdo);
		    	staticVOs.add(vo);
		    }
		    
		    pm.close();
		    return staticVOs;
		} catch (Exception e) {
		    return staticVOs;
		}
	}

	public StarEntryVO addEntry(StarEntryVO newTerm) {
        Long userId=(Long)getThreadLocalRequest().getSession().getAttribute("userid");
        String userName=(String)getThreadLocalRequest().getSession().getAttribute("username");
        newTerm.setUserID(userId);
        newTerm.setUserName(userName);
        StarEntryJDO termJDO = new StarEntryJDO(newTerm);
        
        PersistenceManager pm = PMF.get().getPersistenceManager();
        try {
            pm.makePersistent(termJDO);
        } finally {
            pm.close();
        }
        newTerm.setId(termJDO.getId());
        starEntryVOs.add(newTerm);
        //starEntryJDOs.add(termJDO);

        return newTerm;
	}

	private StarEntryVO getEntryVO(StarEntryJDO entryJDO) {
        Iterator iterator=starEntryVOs.iterator();
        while (iterator.hasNext()) {
        	StarEntryVO currentVO=(StarEntryVO)iterator.next();
        	if (currentVO.getId().longValue()==entryJDO.getId().longValue()) {
        		return currentVO;
        	}
        }
        
        return null;
	}
	
	public List<StarEntryVO> removeEntry(StarEntryVO newTerm) {
        List<StarEntryVO> deletedEntries=new ArrayList<StarEntryVO>();
        
        PersistenceManager pm = PMF.get().getPersistenceManager();
        try {
            StarEntryJDO termJDO=getJDO(pm, newTerm.getId());
            //termJDO=new StarEntryJDO(newTerm);
 		    //pm.deletePersistent(termJDO);
    	    
            Iterator iterator=termJDO.getAttachments().iterator();
            while (iterator.hasNext()) {
            	Long currentID=(Long)iterator.next();
            	
            	if (currentID!=null) {
	           		StarEntryJDO currentJDO=getJDO(pm, currentID);
	           		if (currentJDO!=null) {
		           		if (currentJDO.getTitle().compareToIgnoreCase("suggestion")==0) {
		           			deletedEntries.add(getEntryVO(currentJDO));
		           			pm.deletePersistent(currentJDO);
		           		} else if (currentJDO.getTitle().compareToIgnoreCase("privilege")==0) {
		           			deletedEntries.add(getEntryVO(currentJDO));
		           			pm.deletePersistent(currentJDO);
		           		} else if (currentJDO.getTitle().compareToIgnoreCase("usecase")==0) {
		           			deletedEntries.add(getEntryVO(currentJDO));
		           			pm.deletePersistent(currentJDO);
		           		} else if (currentJDO.getTitle().compareToIgnoreCase("comment")==0) {
		           			deletedEntries.add(getEntryVO(currentJDO));
		           			pm.deletePersistent(currentJDO);
		           		}
	           		}
            	}
            }
		    pm.deletePersistent(termJDO);
		    if (newTerm!=null)
		    	deletedEntries.add(newTerm);
        } catch (Exception e) {
        	System.out.println(e.toString());
        } finally {
            pm.close();
        }

        return deletedEntries;
	}

	private StarEntryJDO getJDO(PersistenceManager pm, Long id) {
        /*Iterator iterator=starEntryJDOs.iterator();
        while (iterator.hasNext()) {
        	StarEntryJDO currentJDO=(StarEntryJDO)iterator.next();
        	if (currentJDO.getId().longValue()==id.longValue()) {
        		return currentJDO;
        	}
        }
        return null;*/
        //PersistenceManager pm = PMF.get().getPersistenceManager();
   	    String query = "select from " + StarEntryJDO.class.getName()+" where id=="+id;
	    List<StarEntryJDO> starEntryJDOs = (List<StarEntryJDO>) pm.newQuery(query).execute();
	    StarEntryJDO jdo=starEntryJDOs.get(0);
	    //pm.close();
	    return jdo; 
	}
	
	public StarEntryVO updateEntry(StarEntryVO newTerm) {
        Long userId=(Long)getThreadLocalRequest().getSession().getAttribute("userid");
        String userName=(String)getThreadLocalRequest().getSession().getAttribute("username");
        
        PersistenceManager pm = PMF.get().getPersistenceManager();
        try {
            StarEntryJDO termJDO=getJDO(pm, newTerm.getId());
            termJDO.setCaption(newTerm.getCaption());
            termJDO.setAttachments(newTerm.getAttachmentIDs());
            termJDO.setRank(newTerm.getRank());
            termJDO.setDescription(newTerm.getDescription());
            pm.makePersistent(termJDO);
        } finally {
            pm.close();
        }
        
        /*Iterator iterator=starEntryJDOs.iterator();
        boolean notFound=true;
        while (iterator.hasNext() && notFound) {
        	StarEntryJDO currentJDO=(StarEntryJDO)iterator.next();
        	if (currentJDO.getId().longValue()==newTerm.getId().longValue()) {
        		notFound=false;
        		termJDO=currentJDO;
        	}
        }*/
        
/*        termJDO.setCaption(newTerm.getCaption());
        termJDO.setAttachments(newTerm.getAttachmentIDs());
        termJDO.setRank(newTerm.getRank());
        termJDO.setDescription(newTerm.getDescription());*/
        
        /*PersistenceManager pm = PMF.get().getPersistenceManager();
        try {
            pm.makePersistent(termJDO);
        } finally {
            pm.close();
        }*/
        //newTerm.setId(termJDO.getId());

        return newTerm;
	}

	public List<StarEntryVO> convertAll() {
		ArrayList<StarEntryVO> starVOs=new ArrayList<StarEntryVO>();
		
		ArrayList<TermVO> termVOs=new ArrayList<TermVO>();
		
	    PersistenceManager pm = PMF.get().getPersistenceManager();
	    String query = "select from " + TermJDO.class.getName();
	    List<TermJDO> termJDOs = (List<TermJDO>) pm.newQuery(query).execute();
	    
	    Iterator iterator=termJDOs.iterator();
	    while (iterator.hasNext()) {
	    	TermJDO currentTerm=(TermJDO)iterator.next();
	    	
	    	StarEntryJDO starJDO=new StarEntryJDO();
	    	//starJDO.setId(currentTerm.getId());
	    	starJDO.setCaption(currentTerm.getCaption());
	    	starJDO.setTitle("term");
	    	starJDO.setRank(currentTerm.getRank());

	    	StarEntryJDO suggestionJDO=new StarEntryJDO();
	    	suggestionJDO.setCaption(currentTerm.getSuggestion());
	    	suggestionJDO.setTitle("suggestion");
	    	suggestionJDO.setUserName(currentTerm.getUserName());
	    	suggestionJDO.setUserID(currentTerm.getUserId());
	    	pm.makePersistent(suggestionJDO);
	    	starJDO.attach(suggestionJDO.getId());
	    	
	    	StarEntryJDO ucJDO=new StarEntryJDO();
	    	ucJDO.setCaption(currentTerm.getUseCase());
	    	ucJDO.setTitle("usecase");
	    	ucJDO.setUserName(currentTerm.getUserName());
	    	ucJDO.setUserID(currentTerm.getUserId());
	    	pm.makePersistent(ucJDO);
	    	starJDO.attach(ucJDO.getId());
	    	
	    	starJDO.setUserName(currentTerm.getUserName());
	    	starJDO.setUserID(currentTerm.getUserId());
	    	
	    	pm.makePersistent(starJDO);
	    }
	    
	    pm.close();
	    
	    return starVOs;
	}

	public List<StarEntryVO> search(String termPattern) {
		ArrayList<StarEntryVO> starEntryVOs=new ArrayList<StarEntryVO>();
		
	    PersistenceManager pm = PMF.get().getPersistenceManager();
	    String query = "select from " + StarEntryJDO.class.getName()+" where caption.startsWith(\""+termPattern+"\")";
	    List<StarEntryJDO> starEntryJDOs = (List<StarEntryJDO>) pm.newQuery(query).execute();
	    
	    Iterator iterator=starEntryJDOs.iterator();
	    while (iterator.hasNext()) {
	    	StarEntryJDO currentStarEntry=(StarEntryJDO)iterator.next();
	    	String title=currentStarEntry.getTitle();
	    	StarEntryVO starEntryVO=null;
	    	if (title==null) {
	    		starEntryVO=new StarEntryVO(currentStarEntry);
	    	} else if (title.compareTo("")==0) {
	    		starEntryVO=new StarEntryVO(currentStarEntry);
	    	} else if (title.compareTo("term")==0) {
	    		starEntryVO=new StarTermVO(currentStarEntry);
	    	} else if (title.compareTo("suggestion")==0) {
	    		starEntryVO=new StarSuggestionVO(currentStarEntry);
	    	} else if (title.compareTo("usecase")==0) {
	    		starEntryVO=new StarUseCaseVO(currentStarEntry);
	    	} else {
	    		starEntryVO=new StarEntryVO(currentStarEntry);
	    	}
	    	starEntryVOs.add(starEntryVO);
	    }
	    
	   /* Iterator iterator1=starEntryVOs.iterator();
	    while (iterator1.hasNext()) {
	    	StarEntryVO currentEntry=(StarEntryVO)iterator1.next();
	    	
	    	List<Long> attachmentIDs=currentEntry.getAttachmentIDs();
	    	Iterator iterator2=attachmentIDs.iterator();
	    	while (iterator2.hasNext()) {
	    		Long currentID=(Long)iterator2.next();
	    		
	    		Iterator iterator3=starEntryVOs.iterator();
	    		while (iterator3.hasNext()) {
	    			StarEntryVO currentAttachment=(StarEntryVO)iterator3.next();
	    			
	    			if (currentAttachment.getId().longValue()==currentID.longValue()) {
	    				currentEntry.addAttachment(currentAttachment);
	    			}
	    		}
	    	}
	    }*/
	    
	    pm.close();
	    return starEntryVOs;
	}
	
	public List<StarEntryVO> getAll(List<Long> idList) {
		List<StarEntryVO> starEntryVOs=new ArrayList<StarEntryVO>();
	    PersistenceManager pm = PMF.get().getPersistenceManager();
	    
	    Iterator iterator=idList.iterator();
	    while (iterator.hasNext()) {
		    String query = "select from " + StarEntryJDO.class.getName()+" where id="+((Long)iterator.next()).toString();
		    List<StarEntryJDO> starEntryJDOs = (List<StarEntryJDO>) pm.newQuery(query).execute();

		    StarEntryJDO currentStarEntry=starEntryJDOs.get(0);
	    	String title=currentStarEntry.getTitle();
	    	StarEntryVO starEntryVO=null;
	    	if (title==null) {
	    		starEntryVO=new StarEntryVO(currentStarEntry);
	    	} else if (title.compareTo("")==0) {
	    		starEntryVO=new StarEntryVO(currentStarEntry);
	    	} else if (title.compareTo("term")==0) {
	    		starEntryVO=new StarTermVO(currentStarEntry);
	    	} else if (title.compareTo("suggestion")==0) {
	    		starEntryVO=new StarSuggestionVO(currentStarEntry);
	    	} else if (title.compareTo("usecase")==0) {
	    		starEntryVO=new StarUseCaseVO(currentStarEntry);
	    	} else {
	    		starEntryVO=new StarEntryVO(currentStarEntry);
	    	}
	    	starEntryVOs.add(starEntryVO);
	    }
	    
	    pm.close();
	    return starEntryVOs;
	}
}